// 10.2 初识泛型算法
/**
 * 标准库提供了超过100个算法。幸运的是，与容器类似，这些算法有一致的结构。
 * 比起死记硬背全部100多个算法，理解此结构可以帮助我们更容易地学习和使用这些算法。
 * 除了少数例外，标准库算法都对一个范围内的元素进行操作。我们将此元素范围称为“输入范围”。
 * 接受输入范围的算法总是使用前两个参数来表示此范围，两个参数分别是指向要处理的第一个元素和尾元素之后位置的迭代器。
 */

#include <iterator>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
#include <string>
#include <array>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
using std::swap;
using std::vector, std::list, std::deque, std::forward_list, std::string, std::array, std::stack, std::queue;
#include "../Chapter07/Sales_data.h"
#include <iostream>
using std::begin, std::cbegin, std::end, std::cend, std::find, std::accumulate, std::equal, std::fill, std::fill_n, std::back_inserter;
using std::cin, std::cout, std::endl;
using std::copy, std::replace, std::replace_copy, std::sort, std::unique;

void elimDups(vector<string> &words);

int main()
{
    // 10.2.3 重排容器元素的算法
    // 调用sort会重排输入序列中的元素，使之有序，它是利用元素类型的<运算符来实现排序的。
    vector<string> words{"1","3","2","5","6","4","2","9","7","8","4","0"};
    elimDups(words);
    for (string s : words)
    {
        cout << s << endl; // 输出0123456789
    }
    // 标准库算法对迭代器而不是容器进行操作。因此，算法不能（直接）添加或删除元素。

    // 使用容器操作删除元素
    // 为了真正地删除无用元素，我们必须使用容器操作，本例中使用erase（参见9.3.3节，第311页）。
    // 我们删除从end_unique开始直至words末尾的范围内的所有元素。
    
    return 0;
}

void elimDups(vector<string> &words)
{
    // 按字典排序words，以便查找重复单词
    sort(words.begin(), words.end());
    // unique重排输入范围，使得每个单词只出现一次
    // 排列在范围的前部，返回指向不重复区域之后一个位置的迭代器
    auto end_unique = unique(words.begin(), words.end());
    // 使用向量操作erase删除重复单词
    words.erase(end_unique,words.end());
}
